import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;


import java.awt.Color;


import java.awt.Font;

import java.awt.Polygon;
import java.io.PrintStream;

import java.util.Locale;
import java.util.Random; 



import pluginUtils.Circle;
import pluginUtils.Complexe; 
import pluginUtils.MobiusTransform;
import pluginUtils.CircleInversion;
import pluginUtils.Pos3D;
import pluginUtils.Sphere;
import pluginUtils.SphereInversion;


public class SphereInversionEx extends ImagePlus implements PlugIn{
	{Locale.setDefault(Locale.US); }
	
	private ImageProcessor primeIP; 
	private int X=2000,Y=2000; // image size
	private double rayon=0.1; 
	private double rayonVerre=100; 
	private double jump=6.0*Math.sqrt(2.0/3)*rayon; 
	
	
	private PrintStream output; 
	private Random generator=new Random(); // One always needs some randomness
	
	// For the scaling of the image
	private double x0=0,x1=1,y0=0,y1=1;
	private double acoef,ccoef,vcoef,wcoef; 
	
	private String[] palette={"Green","Red","Blue","Yellow","White","NavyBlue","Turquoise","Orange"};
	private Color[] palette1={Color.YELLOW,Color.RED,Color.BLUE,Color.GREEN,Color.MAGENTA,Color.ORANGE};
	public void setCoefs(){
		acoef=X/(x1-x0); 
		vcoef=Y/(y1-y0); 
		ccoef=-acoef*x0; 
		wcoef=-vcoef*y0; 
	}
	 
	
	
	public void setBounds(double xl,double xu,double yl,double yu){
		x0=xl; 
		x1=xu;
		y0=yl;
		y1=yu; 
	}
	
	
	
	private static int number=0; 
	
	
	
	private void drawPoint(Complexe c){
		double xCenter=c.getReal(); 
		double yCenter=c.getIm(); 
		int intX=(int)(xCenter*acoef+ccoef);
		int intY=(int)(yCenter*vcoef+wcoef);
		primeIP.fillOval(intX-10,intY-10,20,20);
	}
	
	
	
	
	
	private void drawLine(double xd,double yd,double xf,double yf){
		int XD=(int)(xd*acoef+ccoef); 
		int YD=(int)(yd*vcoef+wcoef); 
		int XF=(int)(xf*acoef+ccoef); 
		int YF=(int)(yf*vcoef+wcoef);
		primeIP.drawLine(XD,YD,XF,YF); 
	}
	
	
	
	public void run(String arg) {
		primeIP = new ColorProcessor(X,Y);
		
		
		double limit=10; 
	
		setBounds(-limit,limit,-limit,limit); 
		setCoefs(); 
		
		
		
		
		
		
		Polygon background=new Polygon(new int[]{0,0,X,Y},new int[]{0,X,Y,0},4);
		primeIP.setColor(Color.WHITE);
		
		primeIP.fillPolygon(background);
		
		
		primeIP.setFont(new Font(null,Font.ITALIC,60));
		primeIP.setColor(Color.BLACK);
		primeIP.setLineWidth(5); 
		
		double horizon=limit; 
		// Inverter
		SphereInversion cinv=new SphereInversion(new Sphere(new Pos3D(0,0,0),1));
		//drawColoredCircle(cinv.getCi(),4);
		cinv.getCi().setColorIndex(1); 
		
		setProcessor("Verifying", primeIP);
		
		drawLine(x0,0,x1,0);
		drawLine(0,y0,0,y1);
		
		try{
			output=new PrintStream("SIEx.txt"); 
			output.println("//Inverting sphere : "); 
			output.println("sphere{<0.0,0.0,0.0>,1.0 texture{pigment {color rgbt<1,0,0,0.8>}} finish {reflection 0.0}}");
			//output.println(cinv.getCi());
		
			
			double cx=-horizon;
			double cy; 
			boolean tic=false; 
			
			int cyclex=0; 
			while(cx<horizon){
				int cycley=0; 
				if(tic) cy=-horizon; else cy=-horizon+rayon;
				while(cy<horizon){
					for(int i=0;i<1;i++){
					
					if(cx*cx+cy*cy<limit*limit){
					Pos3D centrum=new Pos3D(1.1,cx ,cy); 
					Sphere c1=new Sphere(centrum,rayon); 
					
					
					c1.setColorIndex(cycley%6);
					output.println(c1);
					Sphere image=cinv.inverte(c1); 
					image.setColorIndex(cycley%6); 
					output.println(image);
					}
					
					}
					cy+=rayon*2; 
					cycley=cycley+1; 
					}// cy
				cyclex=cyclex+1; 
				cx=cx+Math.sqrt(3)*rayon; 
				tic=!tic; 
			
				System.out.println(cx); 
			}// cx
			
			
			
		
		
		}
		catch (Exception e) {
			System.out.println("plante "+e); 
		}
		
		
	//	show();
		System.out.println("done "+number); 
	}	
}
	